/***************************************************************************
 *   Copyright (C) 2007-2009 by Elad Lahav
 *   elad_lahav@users.sourceforge.net
 *
 *   This program is free software; you can redistribute it and/or modify
 *   it under the terms of the GNU General Public License as published by
 *   the Free Software Foundation; either version 2 of the License, or
 *   (at your option) any later version.
 *
 *   This program is distributed in the hope that it will be useful,
 *   but WITHOUT ANY WARRANTY; without even the implied warranty of
 *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *   GNU General Public License for more details.
 *
 *   You should have received a copy of the GNU General Public License
 *   along with this program; if not, write to the
 *   Free Software Foundation, Inc.,
 *   59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
 ***************************************************************************/

#ifndef __CSCOPE_CROSSREF_H__
#define __CSCOPE_CROSSREF_H__

#include "cscope.h"
#include "ctags.h"
#include "engineconfigwidget.h"

namespace KScope
{

namespace Cscope
{

/**
 * Manages a Cscope cross-reference database.
 * The cross-reference database generated by Cscope is stored in a cscope.out
 * file, as well as optional inverted-index files. This class creates
 * independent Cscope processes used to query and build these files. When
 * building the cross-reference database, Cscope uses temporary files, so that
 * the existing database can still be queried.
 * @author Elad Lahav
 */
class Crossref : public Core::Engine
{
	Q_OBJECT

public:
	Crossref(QObject* parent = 0);
	~Crossref();

	void open(const QString&, Core::Callback<>*);

	/**
	 * @return The current status of the database.
	 */
	Status status() const { return status_; }

	QList<Core::Location::Fields> queryFields(Core::Query::Type) const;

public slots:
	void query(Core::Engine::Connection*, const Core::Query&) const;
	void build(Core::Engine::Connection*) const;

	const QString& path() { return path_; }

private:
	/**
	 * The path of the directory containing the cscope.out file.
	 */
	QString path_;

	/**
	 * Command-line arguments to Cscope.
	 */
	QStringList args_;

	/**
	 * The current status of the database.
	 */
	Status status_;

private slots:
	void buildProcessFinished(int, QProcess::ExitStatus);
};

} // namespace Cscope

namespace Core
{

/**
 * Provides configuration management for the Cscope/Ctags engine.
 */
template<>
struct EngineConfig<Cscope::Crossref>
{
	static QString name() { return "Cscope"; }

	static void getConfig(KeyValuePairs& confParams) {
		confParams["CscopePath"] = Cscope::Cscope::execPath_;
		confParams["CtagsPath"] = Cscope::Ctags::execPath_;
	}

	static void setConfig(const KeyValuePairs& confParams) {
		QString cscopePath = confParams["CscopePath"].toString();
		if (!cscopePath.isEmpty())
			Cscope::Cscope::execPath_ = cscopePath;

		QString ctagsPath = confParams["CtagsPath"].toString();
		if (!ctagsPath.isEmpty())
			Cscope::Ctags::execPath_ = ctagsPath;
	}

	static QWidget* createConfigWidget(QWidget* parent) {
		Cscope::EngineConfigWidget* widget
			= new Cscope::EngineConfigWidget(parent);
		qDebug() << Cscope::Cscope::execPath_ << Cscope::Ctags::execPath_;
		widget->cscopePathEdit_->setText(Cscope::Cscope::execPath_);
		widget->ctagsPathEdit_->setText(Cscope::Ctags::execPath_);
		return widget;
	}

	static void configFromWidget(QWidget* widget) {
		Cscope::EngineConfigWidget* configWidget
			= dynamic_cast<Cscope::EngineConfigWidget*>(widget);
		if (configWidget == NULL)
			return;

		Cscope::Cscope::execPath_ = configWidget->cscopePath();
		Cscope::Ctags::execPath_ = configWidget->ctagsPath();
	}
};

} // namespace Core

} // namespace KScope

#endif // __CSCOPE_CROSSREF_H__
